package com.carrental.search.service.impl;

import com.carrental.common.api.PageResult;
import com.carrental.search.model.document.VehicleDocument;
import com.carrental.search.repository.VehicleRepository;
import com.carrental.search.service.VehicleSearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 车辆搜索服务降级实现类
 * 当Elasticsearch不可用时使用，提供基本的内存存储功能
 */
@Slf4j
@Service
@ConditionalOnProperty(name = "spring.elasticsearch.repositories.enabled", havingValue = "false")
public class VehicleSearchServiceFallback implements VehicleSearchService {

    @Resource
    private VehicleRepository vehicleRepository;

    @Override
    public VehicleDocument saveVehicle(VehicleDocument vehicleDocument) {
        log.warn("使用降级VehicleSearchService: saveVehicle");
        return vehicleRepository.save(vehicleDocument);
    }

    @Override
    public Iterable<VehicleDocument> saveVehicles(List<VehicleDocument> vehicleDocuments) {
        log.warn("使用降级VehicleSearchService: saveVehicles");
        return vehicleRepository.saveAll(vehicleDocuments);
    }

    @Override
    public VehicleDocument getVehicleById(Long id) {
        log.warn("使用降级VehicleSearchService: getVehicleById");
        Optional<VehicleDocument> optionalVehicle = vehicleRepository.findById(id);
        return optionalVehicle.orElse(null);
    }

    @Override
    public void deleteVehicleById(Long id) {
        log.warn("使用降级VehicleSearchService: deleteVehicleById");
        vehicleRepository.deleteById(id);
    }

    @Override
    public PageResult<VehicleDocument> searchVehicles(String keyword, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: searchVehicles");
        List<VehicleDocument> result = new ArrayList<>(((List<VehicleDocument>)vehicleRepository.findByKeyword(keyword)));
        return createPageResult(result, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> advancedSearchVehicles(Map<String, Object> params, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: advancedSearchVehicles - 返回简化结果");
        List<VehicleDocument> allVehicles = new ArrayList<>();
        vehicleRepository.findAll().forEach(allVehicles::add);
        
        // 简单过滤逻辑
        List<VehicleDocument> filteredVehicles = allVehicles.stream()
                .filter(vehicle -> filterByParams(vehicle, params))
                .collect(Collectors.toList());
        
        return createPageResult(filteredVehicles, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> searchVehiclesByBrand(String brand, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: searchVehiclesByBrand");
        List<VehicleDocument> result = vehicleRepository.findByBrand(brand);
        return createPageResult(result, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> searchVehiclesByType(String type, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: searchVehiclesByType");
        List<VehicleDocument> result = vehicleRepository.findByType(type);
        return createPageResult(result, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> searchVehiclesByPriceRange(BigDecimal minPrice, BigDecimal maxPrice, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: searchVehiclesByPriceRange");
        List<VehicleDocument> result = vehicleRepository.findByDailyRentBetween(minPrice, maxPrice);
        return createPageResult(result, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> searchVehiclesByLocation(double latitude, double longitude, double distance, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: searchVehiclesByLocation - 位置搜索在降级模式下不可用，返回空结果");
        PageResult<VehicleDocument> page = new PageResult<>();
        page.setRecords(Collections.emptyList());
        page.setTotal(0);
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page.setPages(0);
        return page;
    }

    @Override
    public PageResult<VehicleDocument> getRecommendedVehicles(int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: getRecommendedVehicles");
        List<VehicleDocument> result = vehicleRepository.findByRecommended(true);
        return createPageResult(result, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> getHotVehicles(int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: getHotVehicles - 返回简化结果");
        List<VehicleDocument> allVehicles = new ArrayList<>();
        vehicleRepository.findAll().forEach(allVehicles::add);
        
        // 简单排序逻辑，假设viewCount表示热度
        allVehicles.sort((v1, v2) -> {
            Integer viewCount1 = v1.getViewCount() != null ? v1.getViewCount() : 0;
            Integer viewCount2 = v2.getViewCount() != null ? v2.getViewCount() : 0;
            return viewCount2.compareTo(viewCount1); // 降序排列
        });
        
        return createPageResult(allVehicles, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> getHighRatedVehicles(Float minRating, int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: getHighRatedVehicles");
        List<VehicleDocument> result = vehicleRepository.findByRatingBetween(minRating, 5.0f);
        return createPageResult(result, pageNum, pageSize);
    }

    @Override
    public PageResult<VehicleDocument> getNewestVehicles(int pageNum, int pageSize) {
        log.warn("使用降级VehicleSearchService: getNewestVehicles - 返回简化结果");
        List<VehicleDocument> allVehicles = new ArrayList<>();
        vehicleRepository.findAll().forEach(allVehicles::add);
        
        // 按创建时间降序排序
        allVehicles.sort((v1, v2) -> {
            Date createTime1 = v1.getCreateTime() != null ? v1.getCreateTime() : new Date(0);
            Date createTime2 = v2.getCreateTime() != null ? v2.getCreateTime() : new Date(0);
            return createTime2.compareTo(createTime1); // 降序排列
        });
        
        return createPageResult(allVehicles, pageNum, pageSize);
    }

    @Override
    public VehicleDocument updateVehicleStatus(Long id, Integer status) {
        log.warn("使用降级VehicleSearchService: updateVehicleStatus");
        Optional<VehicleDocument> optionalVehicle = vehicleRepository.findById(id);
        if (optionalVehicle.isPresent()) {
            VehicleDocument vehicle = optionalVehicle.get();
            vehicle.setStatus(status);
            return vehicleRepository.save(vehicle);
        }
        return null;
    }

    @Override
    public boolean incrementViewCount(Long id) {
        log.warn("使用降级VehicleSearchService: incrementViewCount");
        Optional<VehicleDocument> optionalVehicle = vehicleRepository.findById(id);
        if (optionalVehicle.isPresent()) {
            VehicleDocument vehicle = optionalVehicle.get();
            Integer viewCount = vehicle.getViewCount() != null ? vehicle.getViewCount() : 0;
            vehicle.setViewCount(viewCount + 1);
            vehicleRepository.save(vehicle);
            return true;
        }
        return false;
    }

    /**
     * 创建分页结果
     */
    private PageResult<VehicleDocument> createPageResult(List<VehicleDocument> list, int pageNum, int pageSize) {
        // 计算总记录数
        long total = list.size();
        
        // 计算起始索引和结束索引
        int fromIndex = (pageNum - 1) * pageSize;
        if (fromIndex >= total) {
            PageResult<VehicleDocument> page = new PageResult<>();
            page.setRecords(Collections.emptyList());
            page.setTotal((int) total);
            page.setCurrent(pageNum);
            page.setSize(pageSize);
            page.setPages((int) Math.ceil((double) total / pageSize));
            return page;
        }
        
        int toIndex = Math.min(fromIndex + pageSize, (int) total);
        List<VehicleDocument> pageData = list.subList(fromIndex, toIndex);
        
        PageResult<VehicleDocument> page = new PageResult<>();
        page.setRecords(pageData);
        page.setTotal((int) total);
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page.setPages((int) Math.ceil((double) total / pageSize));
        return page;
    }

    /**
     * 根据参数过滤车辆
     */
    private boolean filterByParams(VehicleDocument vehicle, Map<String, Object> params) {
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            
            if (value == null) {
                continue;
            }
            
            switch (key) {
                case "brand":
                    if (!value.toString().equals(vehicle.getBrand())) {
                        return false;
                    }
                    break;
                case "model":
                    if (!value.toString().equals(vehicle.getModel())) {
                        return false;
                    }
                    break;
                case "type":
                    if (!value.toString().equals(vehicle.getType())) {
                        return false;
                    }
                    break;
                case "status":
                    if (!value.equals(vehicle.getStatus())) {
                        return false;
                    }
                    break;
                case "seats":
                    if (!value.equals(vehicle.getSeats())) {
                        return false;
                    }
                    break;
                case "minDailyRent":
                    if (vehicle.getDailyRent() == null || 
                        vehicle.getDailyRent().compareTo(new BigDecimal(value.toString())) < 0) {
                        return false;
                    }
                    break;
                case "maxDailyRent":
                    if (vehicle.getDailyRent() == null || 
                        vehicle.getDailyRent().compareTo(new BigDecimal(value.toString())) > 0) {
                        return false;
                    }
                    break;
                case "recommended":
                    Boolean recommended = Boolean.valueOf(value.toString());
                    if (!recommended.equals(vehicle.getRecommended())) {
                        return false;
                    }
                    break;
                case "minRating":
                    float minRating = Float.parseFloat(value.toString());
                    if (vehicle.getRating() == null || vehicle.getRating() < minRating) {
                        return false;
                    }
                    break;
                case "maxRating":
                    float maxRating = Float.parseFloat(value.toString());
                    if (vehicle.getRating() == null || vehicle.getRating() > maxRating) {
                        return false;
                    }
                    break;
                case "keyword":
                    String keyword = value.toString().toLowerCase();
                    boolean containsKeyword = (vehicle.getName() != null && vehicle.getName().toLowerCase().contains(keyword)) ||
                                            (vehicle.getBrand() != null && vehicle.getBrand().toLowerCase().contains(keyword)) ||
                                            (vehicle.getModel() != null && vehicle.getModel().toLowerCase().contains(keyword));
                    if (!containsKeyword) {
                        return false;
                    }
                    break;
                default:
                    // 忽略未知参数
                    break;
            }
        }
        
        return true;
    }
} 